using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TrackSystem.IO.Data;
using TrackSystem.IO.Models;

namespace TrackSystem.IO.Protocol
{

    /// <summary>
    /// USBL通信协议 "$PSIMSSB,hhmmss.sss,B48,A,,D,N,M,<usbl_lat>,N,<usbl_lon>,E,<usbl_depth>,Expected_accuracy,N,,*hh<LR><LF>"
    /// 示例：$PSIMSSB,105924.637,B48,A,,D,N,M,2229.67598,N,11350.65573,E,156.361,1.812,N,,*69<LR><LF>
    /// 0--信1标号;
    /// 1--信标1纬度 N-正,S-负;
    /// 2--信标1经度 E-正,W-负;
    /// 3--信标1深度;
    /// 4--;
    /// 5--信2标号;
    /// 6--信标2纬度 N-正,S-负;
    /// 7--信标2经度 E-正,W-负;
    /// 8--信标2深度;
    /// 9--;
    /// 13--最大支持10个目标;
    /// </summary>
    public class USBLProtocol : ProtocolBase
    {
        private int startTicks;
        private bool bSendR;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="name"></param>
        public USBLProtocol(string name)
            : base()
        {
            NeedInit = false;
            Name = name;
            bSendR = false;
        }

        /// <summary>
        /// 生成读取寄存器的通讯帧
        /// </summary>
        /// <returns></returns>
        public override byte[] GenerateReadFrame(out int NeedRecvLen)
        {
            startTicks = Environment.TickCount;
            if (bSendR)
            {
                Fail_R++;
                // 失败超过10次，成功次数清零
                if (Fail_R >= 10)
                {
                    Succ_R = 0;
                }
            }
            bSendR = true;
            NeedRecvLen = 60;
            return null;
        }


        /// <summary>
        /// 根据收到的内容进行处理
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns></returns>
        public override bool ProcessReadFrame(byte[] buffer)
        {
            var DataFactory = RegFactory.Instance;
            Lapse = Environment.TickCount - startTicks;
            try
            {
                string frame = Encoding.UTF8.GetString(buffer);
                string[] ar_line = frame.Split('\n');
                try
                {
                    for (int i = 0; i < ar_line.Length; i++)
                    {
                        string[] ar_str = ar_line[i].Split(',');
                        Rx_r = buffer;  // 用于显示的接收帧内容
                        int strLen = ar_str.Length;

                        if (strLen < 6)   // 数据长度小于6
                        {
                            continue;
                        }
                        // $PSIMSSB,105924.637,B48,A,,D,N,M,2229.67598,N,11350.65573,E,156.361,1.812,N,,*69<LR><LF>
                        if (ar_str[0] == "$PSIMSSB" && ar_str[5] == "D" && strLen == 17)
                        {
                            bSendR = false;
                            if (strLen >= 11)
                            { //目标
                                string beaconNum = ar_str[2]; // 目标编号
                                double d8 = double.Parse(ar_str[8]); // 目标纬度
                                int d8_temp = (int)(d8 / 100); // 提取度
                                double d8_temp2 = (d8 - d8_temp * 100) / 60;// 分转化为度
                                double d8_all = Math.Round(d8_temp + d8_temp2, 7);
                                if (ar_str[9] == "S")
                                {
                                    d8_all = -1 * d8_all;
                                }
                                double d10 = double.Parse(ar_str[10]); // 目标经度
                                int d10_temp = (int)(d10 / 100); // 提取度
                                double d10_temp2 = (d10 - d10_temp * 100) / 60;// 分转化为度
                                double d10_all = Math.Round(d10_temp + d10_temp2, 7);
                                if (ar_str[11] == "W")
                                {
                                    d10_all = -1 * d10_all;
                                }
                                // 深度提取
                                double d12 = double.Parse(ar_str[12]); // 目标深度
                                if (beaconNum == "B48") // 模拟信标
                                {
                                    string num_str = beaconNum.Substring(1);
                                    double num = double.Parse(num_str);
                                    DataFactory.SetVal(RegNameList[0], num);
                                    DataFactory.SetVal(RegNameList[1], d8_all);
                                    DataFactory.SetVal(RegNameList[2], d10_all);
                                    DataFactory.SetVal(RegNameList[3], d12);
                                } else if (beaconNum == "M07") // 采矿车信标1（前面）
                                {
                                    string num_str = beaconNum.Substring(1);
                                    double num = double.Parse(num_str);
                                    DataFactory.SetVal(RegNameList[5], num);
                                    DataFactory.SetVal(RegNameList[6], d8_all);
                                    DataFactory.SetVal(RegNameList[7], d10_all);
                                    DataFactory.SetVal(RegNameList[8], d12);
                                }
                                else if (beaconNum == "M21") // 采矿车信标2（后面）
                                {
                                    string num_str = beaconNum.Substring(1);
                                    double num = double.Parse(num_str);
                                    DataFactory.SetVal(RegNameList[10], num);
                                    DataFactory.SetVal(RegNameList[11], d8_all);
                                    DataFactory.SetVal(RegNameList[12], d10_all);
                                    DataFactory.SetVal(RegNameList[13], d12);
                                }
                                else if (beaconNum == "M14") // 
                                {
                                    string num_str = beaconNum.Substring(1);
                                    double num = double.Parse(num_str);
                                    DataFactory.SetVal(RegNameList[15], num);
                                    DataFactory.SetVal(RegNameList[16], d8_all);
                                    DataFactory.SetVal(RegNameList[17], d10_all);
                                    DataFactory.SetVal(RegNameList[18], d12);
                                }
                                else if (beaconNum == "M08")
                                {
                                    string num_str = beaconNum.Substring(1);
                                    double num = double.Parse(num_str);
                                    DataFactory.SetVal(RegNameList[20], num);
                                    DataFactory.SetVal(RegNameList[21], d8_all);
                                    DataFactory.SetVal(RegNameList[22], d10_all);
                                    DataFactory.SetVal(RegNameList[23], d12);
                                }
                                else if (beaconNum == "M20") // 采矿车信标
                                {
                                    string num_str = beaconNum.Substring(1);
                                    double num = double.Parse(num_str);
                                    DataFactory.SetVal(RegNameList[25], num);
                                    DataFactory.SetVal(RegNameList[26], d8_all);
                                    DataFactory.SetVal(RegNameList[27], d10_all);
                                    DataFactory.SetVal(RegNameList[28], d12);
                                }
                                else if (beaconNum == "M15") // 采矿车信标
                                {
                                    string num_str = beaconNum.Substring(1);
                                    double num = double.Parse(num_str);
                                    DataFactory.SetVal(RegNameList[30], num);
                                    DataFactory.SetVal(RegNameList[31], d8_all);
                                    DataFactory.SetVal(RegNameList[32], d10_all);
                                    DataFactory.SetVal(RegNameList[33], d12);
                                }
                                else if (beaconNum == "M16") // 采矿车信标
                                {
                                    string num_str = beaconNum.Substring(1);
                                    double num = double.Parse(num_str);
                                    DataFactory.SetVal(RegNameList[35], num);
                                    DataFactory.SetVal(RegNameList[36], d8_all);
                                    DataFactory.SetVal(RegNameList[37], d10_all);
                                    DataFactory.SetVal(RegNameList[38], d12);
                                }
                                else if (beaconNum == "M17") // 采矿车信标
                                {
                                    string num_str = beaconNum.Substring(1);
                                    double num = double.Parse(num_str);
                                    DataFactory.SetVal(RegNameList[40], num);
                                    DataFactory.SetVal(RegNameList[41], d8_all);
                                    DataFactory.SetVal(RegNameList[42], d10_all);
                                    DataFactory.SetVal(RegNameList[43], d12);
                                }
                                else if (beaconNum == "M18") // 采矿车信标
                                {
                                    string num_str = beaconNum.Substring(1);
                                    double num = double.Parse(num_str);
                                    DataFactory.SetVal(RegNameList[45], num);
                                    DataFactory.SetVal(RegNameList[46], d8_all);
                                    DataFactory.SetVal(RegNameList[47], d10_all);
                                    DataFactory.SetVal(RegNameList[48], d12);
                                }
                                else if (beaconNum == "M19") // 采矿车信标2（后面）
                                {
                                    string num_str = beaconNum.Substring(1);
                                    double num = double.Parse(num_str);
                                    DataFactory.SetVal(RegNameList[50], num);
                                    DataFactory.SetVal(RegNameList[51], d8_all);
                                    DataFactory.SetVal(RegNameList[52], d10_all);
                                    DataFactory.SetVal(RegNameList[53], d12);
                                }
                            }
                        }
                    }
                }
                catch (Exception)
                {
                    return false;
                }
                if (!bSendR)
                    Succ_R++;
                // 失败次数清零
                if (Succ_R > 0 && Fail_R > 0)
                {
                    Fail_R = 0;
                }
            }
            catch (Exception)
            {
                return false;
            }
            return true;
        } 
    }
}
